﻿#pragma once

#include <hacks/base/hacks_conf.h>
#include <hacks/base/ev_loop.h>

namespace hacks {
    class ev_async;

    SHARED_TYPE(ev_async);

    typedef std::function<void(ev_async &)> ev_async_functor_t;

    class ev_async : public std::enable_shared_from_this<ev_async> {

    DISABLE_COPY_MOVE(ev_async)

    public:

        ev_async(const shared_ev_loop &loop,
                 ev_async_functor_t &&async_f);

        ev_async(const shared_ev_loop &loop,
                 ev_async_functor_t &&async_f,
                 ev_async_functor_t &&close_f);

        ~ev_async();

        void commit();

        void active();

        void stop_async_task();

        void set_userdata(void *udata);

        void *get_userdata() const;

    private:
        void init();

        static void uv_async_callback(uv_async_t *async);

        void async_actived();

        static void uv_async_close_callback(uv_handle_t *h);

        void async_closed();

    private:
        shared_ev_loop event_loop_;
        uv_async_t *async_;
        ev_async_functor_t ev_async_active_functor_;
        ev_async_functor_t ev_async_closed_functor_;
        std::once_flag commit_once_flag_;
        std::atomic<ev_evt_state> async_status_;
        void *user_data_;
    };
}
